from typing import Any, List, Optional

from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.ext.asyncio import AsyncSession

from app.api import deps
from app.models.user import User
from app.schemas.resource import (
    ResourceCreate, ResourceUpdate, ResourceResponse,
    ProjectResourceAllocationCreate, TaskResourceAllocationCreate,
    ResourceAllocationUpdate,
    ProjectResourceAllocationResponse, TaskResourceAllocationResponse
)
from app.services import resource as resource_service


router = APIRouter()


# 资源相关路由
@router.get("/", response_model=List[ResourceResponse])
async def read_resources(
    db: AsyncSession = Depends(deps.get_db),
    skip: int = 0,
    limit: int = 100,
    resource_type: Optional[str] = None,
    is_available: Optional[bool] = None,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """获取资源列表，可按资源类型和可用性筛选"""
    resources = await resource_service.get_resources(
        db=db, skip=skip, limit=limit,
        resource_type=resource_type, is_available=is_available
    )
    return resources


@router.post("/", response_model=ResourceResponse, status_code=status.HTTP_201_CREATED)
async def create_resource(
    *,
    db: AsyncSession = Depends(deps.get_db),
    resource_in: ResourceCreate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """创建资源"""
    # 检查权限：只有超级用户可以创建资源
    if not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions",
        )
    resource = await resource_service.create_resource(db=db, obj_in=resource_in)
    return resource


@router.get("/{resource_id}", response_model=ResourceResponse)
async def read_resource(
    *,
    db: AsyncSession = Depends(deps.get_db),
    resource_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """获取特定资源详情"""
    resource = await resource_service.get_resource_by_id(db=db, id=resource_id)
    if not resource:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Resource not found",
        )
    return resource


@router.put("/{resource_id}", response_model=ResourceResponse)
async def update_resource(
    *,
    db: AsyncSession = Depends(deps.get_db),
    resource_id: int,
    resource_in: ResourceUpdate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """更新资源"""
    resource = await resource_service.get_resource_by_id(db=db, id=resource_id)
    if not resource:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Resource not found",
        )
    # 检查权限：只有超级用户可以更新资源
    if not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions",
        )
    resource = await resource_service.update_resource(db=db, db_obj=resource, obj_in=resource_in)
    return resource


@router.delete("/{resource_id}", response_model=ResourceResponse)
async def delete_resource(
    *,
    db: AsyncSession = Depends(deps.get_db),
    resource_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """删除资源"""
    resource = await resource_service.get_resource_by_id(db=db, id=resource_id)
    if not resource:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Resource not found",
        )
    # 检查权限：只有超级用户可以删除资源
    if not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not enough permissions",
        )
    resource = await resource_service.delete_resource(db=db, id=resource_id)
    return resource


# 项目资源分配相关路由
@router.get("/projects/{project_id}/allocations", response_model=List[ProjectResourceAllocationResponse])
async def read_project_resource_allocations(
    *,
    db: AsyncSession = Depends(deps.get_db),
    project_id: int,
    skip: int = 0,
    limit: int = 100,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """获取项目资源分配列表"""
    allocations = await resource_service.get_project_resource_allocations(
        db=db, project_id=project_id, skip=skip, limit=limit
    )
    return allocations


@router.post("/projects/{project_id}/allocations", response_model=ProjectResourceAllocationResponse, status_code=status.HTTP_201_CREATED)
async def create_project_resource_allocation(
    *,
    db: AsyncSession = Depends(deps.get_db),
    project_id: int,
    allocation_in: ProjectResourceAllocationCreate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """创建项目资源分配"""
    # 确保分配关联到正确的项目
    if allocation_in.project_id != project_id:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Allocation must be associated with the specified project",
        )
    # 检查资源是否存在
    resource = await resource_service.get_resource_by_id(db=db, id=allocation_in.resource_id)
    if not resource:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Resource not found",
        )
    allocation = await resource_service.create_project_resource_allocation(
        db=db, obj_in=allocation_in
    )
    return allocation


@router.get("/project-allocations/{allocation_id}", response_model=ProjectResourceAllocationResponse)
async def read_project_resource_allocation(
    *,
    db: AsyncSession = Depends(deps.get_db),
    allocation_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """获取特定项目资源分配详情"""
    allocation = await resource_service.get_project_resource_allocation_by_id(
        db=db, id=allocation_id
    )
    if not allocation:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project resource allocation not found",
        )
    return allocation


@router.put("/project-allocations/{allocation_id}", response_model=ProjectResourceAllocationResponse)
async def update_project_resource_allocation(
    *,
    db: AsyncSession = Depends(deps.get_db),
    allocation_id: int,
    allocation_in: ResourceAllocationUpdate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """更新项目资源分配"""
    allocation = await resource_service.get_project_resource_allocation_by_id(
        db=db, id=allocation_id
    )
    if not allocation:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project resource allocation not found",
        )
    allocation = await resource_service.update_project_resource_allocation(
        db=db, db_obj=allocation, obj_in=allocation_in
    )
    return allocation


@router.delete("/project-allocations/{allocation_id}", response_model=ProjectResourceAllocationResponse)
async def delete_project_resource_allocation(
    *,
    db: AsyncSession = Depends(deps.get_db),
    allocation_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """删除项目资源分配"""
    allocation = await resource_service.get_project_resource_allocation_by_id(
        db=db, id=allocation_id
    )
    if not allocation:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Project resource allocation not found",
        )
    allocation = await resource_service.delete_project_resource_allocation(
        db=db, id=allocation_id
    )
    return allocation


# 任务资源分配相关路由
@router.get("/tasks/{task_id}/allocations", response_model=List[TaskResourceAllocationResponse])
async def read_task_resource_allocations(
    *,
    db: AsyncSession = Depends(deps.get_db),
    task_id: int,
    skip: int = 0,
    limit: int = 100,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """获取任务资源分配列表"""
    allocations = await resource_service.get_task_resource_allocations(
        db=db, task_id=task_id, skip=skip, limit=limit
    )
    return allocations


@router.post("/tasks/{task_id}/allocations", response_model=TaskResourceAllocationResponse, status_code=status.HTTP_201_CREATED)
async def create_task_resource_allocation(
    *,
    db: AsyncSession = Depends(deps.get_db),
    task_id: int,
    allocation_in: TaskResourceAllocationCreate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """创建任务资源分配"""
    # 确保分配关联到正确的任务
    if allocation_in.task_id != task_id:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Allocation must be associated with the specified task",
        )
    # 检查资源是否存在
    resource = await resource_service.get_resource_by_id(db=db, id=allocation_in.resource_id)
    if not resource:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Resource not found",
        )
    allocation = await resource_service.create_task_resource_allocation(
        db=db, obj_in=allocation_in
    )
    return allocation


@router.get("/task-allocations/{allocation_id}", response_model=TaskResourceAllocationResponse)
async def read_task_resource_allocation(
    *,
    db: AsyncSession = Depends(deps.get_db),
    allocation_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """获取特定任务资源分配详情"""
    allocation = await resource_service.get_task_resource_allocation_by_id(
        db=db, id=allocation_id
    )
    if not allocation:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Task resource allocation not found",
        )
    return allocation


@router.put("/task-allocations/{allocation_id}", response_model=TaskResourceAllocationResponse)
async def update_task_resource_allocation(
    *,
    db: AsyncSession = Depends(deps.get_db),
    allocation_id: int,
    allocation_in: ResourceAllocationUpdate,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """更新任务资源分配"""
    allocation = await resource_service.get_task_resource_allocation_by_id(
        db=db, id=allocation_id
    )
    if not allocation:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Task resource allocation not found",
        )
    allocation = await resource_service.update_task_resource_allocation(
        db=db, db_obj=allocation, obj_in=allocation_in
    )
    return allocation


@router.delete("/task-allocations/{allocation_id}", response_model=TaskResourceAllocationResponse)
async def delete_task_resource_allocation(
    *,
    db: AsyncSession = Depends(deps.get_db),
    allocation_id: int,
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """删除任务资源分配"""
    allocation = await resource_service.get_task_resource_allocation_by_id(
        db=db, id=allocation_id
    )
    if not allocation:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Task resource allocation not found",
        )
    allocation = await resource_service.delete_task_resource_allocation(
        db=db, id=allocation_id
    )
    return allocation